package com.hyjiacan.tools.http.handlers

import com.hyjiacan.tools.http.models.RequestContext
import com.hyjiacan.tools.http.exceptions.HTTPException
import com.hyjiacan.tools.http.exceptions.NotFound
import java.io.FileNotFoundException
import java.net.URL


class StaticHandler : BaseHandler(false) {
    @Throws(HTTPException::class)
    override fun get(request: RequestContext): Any {
        val path = request.path
        val info = getFile(path)
        val mime = info.first
        val content = info.second
        request.exchange.responseHeaders.set("Content-Type", mime)
        return content
    }

    override fun post(request: RequestContext): Any {
        TODO("Not yet implemented")
    }

    override fun put(request: RequestContext): Any {
        TODO("Not yet implemented")
    }

    override fun delete(request: RequestContext): Any {
        TODO("Not yet implemented")
    }

    @OptIn(kotlin.ExperimentalStdlibApi::class)
    private fun getFile(filename: String): Pair<String, String> {
        var targetFilename = "/static$filename"
        if (targetFilename.endsWith("/")) {
            targetFilename += "index.html"
        }
        val exePath: String = this.javaClass.protectionDomain.codeSource.location.file
        targetFilename = if (exePath.contains(".jar")) {
            // JAR 环境
            "jar:file:${exePath}!${targetFilename}"
        } else {
            "file://${exePath}${targetFilename}"
        }

        val url = URL(targetFilename)
        val content: String
        try {
            content = url.readText()
        } catch (e: FileNotFoundException) {
            throw NotFound()
        }

        val temp = targetFilename.split('.')
        val mime = if (temp.size > 1) {
            MIME_MAP.getOrDefault(temp.last().lowercase(), MIME_DEFAULT)
        } else {
            MIME_DEFAULT
        }

        return Pair(mime, content)
    }

    companion object {
        val MIME_MAP = mapOf(
            "html" to "text/html; charset=utf-8",
            "js" to "text/javascript; charset=utf-8",
            "json" to "application/json; charset=utf-8",
            "css" to "text/css; charset=utf-8",
            "ico" to "image/vnd.microsoft.icon",
            "ttf" to "font/ttf",
            "woff" to "font/woff",
            "woff2" to "font/woff2",
        )

        const val MIME_DEFAULT = "application/octet-stream"
    }
}